#include "Ros2TransformerVisitor.h"

void Ros2TransformerVisitor::visit(SpecificationNode& node) {
    // 增加DefinitionNode的ROS2命名空间
    addRos2Namespace(nullptr, &node);
    // 递归访问子节点
    DefaultVisitor::visit(node);
}

void Ros2TransformerVisitor::visit(ScopedNameNode& node) {
    // 引用类型时可能需要增加ROS2命名空间
    if (node.components_.size() > 1) {
        // 在倒数第二个组件前添加ROS2命名空间
        std::string* ddsModuleName = new std::string("dds_");
        node.components_.insert(node.components_.end() - 1, ddsModuleName);
    }
}

ASTNode* Ros2TransformerVisitor::addRos2Namespace(ASTNode* parentNode, ASTNode* node) {
    SpecificationNode* specNode = dynamic_cast<SpecificationNode*>(node);
    if (specNode) {
        ListNode<DefinitionNode*> modified;
        for (auto &definition : specNode->definitions_->nodes_) {
            // 如果是模块声明，递归向下添加ROS2命名空间
            ASTNode* transformed = addRos2Namespace(specNode, definition);
            DefinitionNode* defNode = dynamic_cast<DefinitionNode*>(transformed);
            modified.nodes_.push_back(defNode);
        }
        delete specNode->definitions_;
        specNode->definitions_ = new ListNode<DefinitionNode*>(modified);
        return specNode;
    }
    ModuleDclNode* moduleNode = dynamic_cast<ModuleDclNode*>(node);
    if (moduleNode) {
        ListNode<DefinitionNode*> modified;
        for (auto &definition : moduleNode->definitions_->nodes_) {
            // 如果是模块声明，递归向下添加ROS2命名空间
            ASTNode* transformed = addRos2Namespace(moduleNode, definition);
            DefinitionNode* defNode = dynamic_cast<DefinitionNode*>(transformed);
            modified.nodes_.push_back(defNode);
        }
        delete moduleNode->definitions_;
        moduleNode->definitions_ = new ListNode<DefinitionNode*>(modified);
        return moduleNode;
    }
    // else maybe ConstDclNode or TypeDclNode
    ConstDclNode* constNode = dynamic_cast<ConstDclNode*>(node);
    TypeDclNode* typeNode = dynamic_cast<TypeDclNode*>(node);
    if (constNode || typeNode) {
        std::string* ddsModuleName = new std::string("dds_");
        ModuleDclNode* moduleNode = new ModuleDclNode(ddsModuleName, nullptr);
        moduleNode->definitions_ = new ListNode<DefinitionNode*>();
        if (constNode) {
            moduleNode->definitions_->nodes_.push_back(constNode);
        } else if (typeNode) {
            moduleNode->definitions_->nodes_.push_back(typeNode);
        }
        return moduleNode;
    }
    // 其他节点不处理
    return node;
}
